package com.cj.myblog.service.impl;

import com.cj.myblog.constants.Constants;
import com.cj.myblog.constants.ResultEnum;
import com.cj.myblog.common.util.FileUtils;
import com.cj.myblog.common.util.PageUtil;
import com.cj.myblog.dao.PluginRepository;
import com.cj.myblog.model.PageBean;
import com.cj.myblog.model.PluginDo;
import com.cj.myblog.model.Result;
import com.cj.myblog.service.PluginService;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.io.FileUtil;
import com.xiaoleilu.hutool.io.IORuntimeException;
import com.xiaoleilu.hutool.util.BeanUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.hutool.util.XmlUtil;
import com.xiaoleilu.hutool.util.ZipUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Document;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2017-08-30.
 */
@Service
public class PluginServiceImpl implements PluginService {


    @Autowired
    private PluginRepository pluginRepository;

    @Override
    public PageBean<PluginDo> findAll(PluginDo pluginDo) {
        Page<PluginDo> list = null;
        final Pageable pageable = PageUtil.buildPageRequest(pluginDo.getStart(),pluginDo.getLength(),"createTime");
        list = pluginRepository.findAll(pageable);

        //查找插件目录是否有未安装插件
        List<PluginDo> installList = list.getContent();
        List<PluginDo> pluginList = new ArrayList<>(installList);
        String root = Constants.PLUG_ROOT ;
        FileFilter fileFilter = new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                String s = "";
                s = pathname.getName().toLowerCase();
                if (s.endsWith(".zip")){
                    return true;
                }
                return false;
            }
        };
        String preXml = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>";
        List<File> fileList = FileUtil.loopFiles(new File(root),fileFilter);
        for (File f:fileList) {

            String xmlStr = FileUtils.getZipFileContent(f,StrUtil.removeSuffix(f.getName(),".zip")+"/plugin.xml");
            if (StrUtil.isNotEmpty(xmlStr)){
                PluginDo zipPluginDo = new PluginDo();
                Document document = XmlUtil.parseXml(StrUtil.removePrefix(xmlStr,preXml));
                zipPluginDo.setSkuNumber(document.getElementsByTagName("skunumber").item(0).getFirstChild().getNodeValue());
                zipPluginDo.setName(document.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
                zipPluginDo.setAuthor(document.getElementsByTagName("author").item(0).getFirstChild().getNodeValue());
                zipPluginDo.setVersion(document.getElementsByTagName("version").item(0).getFirstChild().getNodeValue());
                zipPluginDo.setPubTime(document.getElementsByTagName("pubtime").item(0).getFirstChild().getNodeValue());
                zipPluginDo.setModifyTime(document.getElementsByTagName("modifytime").item(0).getFirstChild().getNodeValue());
                zipPluginDo.setDescription(document.getElementsByTagName("description").item(0).getFirstChild().getNodeValue());
                zipPluginDo.setStatus(Constants.THREE);
                pluginList.add(zipPluginDo);
            }
        }

        PageBean<PluginDo> pageBean = new PageBean<>(list);
        pageBean.setData(pluginList);
        pageBean.setiTotalRecords((int)list.getTotalElements()+pluginList.size());
        pageBean.setiTotalDisplayRecords((int)list.getTotalElements()+pluginList.size());

     return pageBean;
    }


    @Override
    public PluginDo getUnInstallPlugin(String name) {
        String path = Constants.PLUG_ROOT+name+".zip";
        String preXml = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>";
        File file = new File(path);
        String xmlStr = FileUtils.getZipFileContent(file,name+"/plugin.xml");
        PluginDo zipPluginDo = new PluginDo();
        if (StrUtil.isNotEmpty(xmlStr)) {
            Document document = XmlUtil.parseXml(StrUtil.removePrefix(xmlStr, preXml));
            zipPluginDo.setSkuNumber(document.getElementsByTagName("skunumber").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setName(document.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setAuthor(document.getElementsByTagName("author").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setVersion(document.getElementsByTagName("version").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setPubTime(document.getElementsByTagName("pubtime").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setModifyTime(document.getElementsByTagName("modifytime").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setDescription(document.getElementsByTagName("description").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setUrl(document.getElementsByTagName("url").item(0).getFirstChild().getNodeValue());
            zipPluginDo.setImage(document.getElementsByTagName("image").item(0).getFirstChild().getNodeValue());

            zipPluginDo.setStatus(Constants.THREE);
        }
        return zipPluginDo;
    }


    @Transactional
    @Override
    public Result<String> installPlug(String skuNumber) {
        String root = Constants.PLUG_ROOT+skuNumber;
        String path = root + ".zip";
        try{
            File file = ZipUtil.unzip(path,Constants.PLUG_ROOT);
            //移动静态文件
            File sourceFile = new File(root+"/templates/");
            File targetFile = new File(Constants.PLUG_TPL_ROOT+skuNumber);
            FileUtil.move(sourceFile,targetFile,true);

        }catch (IORuntimeException e){

            return new Result<>(ResultEnum.PLUG_INSTALL_ERROR);
        }

        //写入插件数据到数据库
        Document document = XmlUtil.readXML(root+"/plugin.xml");

        PluginDo pluginDo = new PluginDo();

        //插件后台管理文件是否存在，存在代表插件有后台管理功能
        pluginDo.setIsMain(FileUtil.exist(root + "/PluginAdmin" + skuNumber + ".class")?1:0);
        pluginDo.setSkuNumber(document.getElementsByTagName("skunumber").item(0).getFirstChild().getNodeValue());
        pluginDo.setName(document.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
        pluginDo.setAuthor(document.getElementsByTagName("author").item(0).getFirstChild().getNodeValue());
        pluginDo.setVersion(document.getElementsByTagName("version").item(0).getFirstChild().getNodeValue());
        pluginDo.setPubTime(document.getElementsByTagName("pubtime").item(0).getFirstChild().getNodeValue());
        pluginDo.setModifyTime(document.getElementsByTagName("modifytime").item(0).getFirstChild().getNodeValue());
        pluginDo.setDescription(document.getElementsByTagName("description").item(0).getFirstChild().getNodeValue());
        pluginDo.setStatus(Constants.ONE);
        pluginDo.setCreateTime(new Date());

        pluginRepository.save(pluginDo);

        //删除压缩包
        FileUtil.del(path);

        return new Result<>();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void uninstall(Long id, String skuNumber) {
        pluginRepository.delete(id);

        String plugRoot = Constants.PLUG_ROOT+skuNumber;
        String plugTplRoot = Constants.PLUG_TPL_ROOT+skuNumber;
        FileUtil.del(plugRoot);
        FileUtil.del(plugTplRoot);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(PluginDo pluginDo) {
        if (pluginDo.getId() == null){
            String javaRoot = Constants.options.get("devPath") + Constants.PLUG_JAVA_SOURCE_ROOT + pluginDo.getSkuNumber();

            String htmlRoot = Constants.options.get("devPath") + Constants.PLUG_HTML_SOURCE_ROOT + pluginDo.getSkuNumber();

            if (pluginDo.getIsMain() == Constants.THREE ||
                    pluginDo.getIsMain() == Constants.ONE){

                String date = DateUtil.now();

                String pluginAdminTpl = StrUtil.format(Constants.PLUGIN_ADMIN_TPL,
                        pluginDo.getSkuNumber(),
                        pluginDo.getAuthor(),
                        pluginDo.getDescription(),
                        date,
                        pluginDo.getSkuNumber(),
                        StrUtil.upperFirst(pluginDo.getSkuNumber())
                        );

                String pluginAdminPath = javaRoot + "/PluginAdmin" + StrUtil.upperFirst(pluginDo.getSkuNumber()) + ".java";

                //生成后台文件
                File pluginAdminFile = FileUtil.touch(pluginAdminPath);

                FileUtil.writeUtf8String(pluginAdminTpl,pluginAdminFile);

                //生成前端文件
                FileUtil.mkdir(htmlRoot + "/static/");

                File pluginHtmlFile = FileUtil.touch(htmlRoot + "/index.ftl");

                FileUtil.writeUtf8String(Constants.PLUGIN_INDEX_TPL,pluginHtmlFile);

                pluginDo.setIsMain(Constants.ONE);
            }

            pluginDo.setCreateTime(new Date());
            pluginRepository.save(pluginDo);

        }

        if (pluginDo.getId() != null){

            PluginDo DO = pluginRepository.findOne(pluginDo.getId());

            BeanUtil.copyProperties(pluginDo,DO, BeanUtil.CopyOptions.create().setIgnoreNullValue(true));
        }

    }

    @Override
    public List<PluginDo> findAllByStatus() {
       List<PluginDo>  list = pluginRepository.findAllByStatus();
        return list;
    }

    @Override
    public Result<String> export(Long id) {
        //pluginRepository.

        return null;
    }


}
